/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#pragma once

#include "../节点.h"
#include <面/面.h>
#include <物理/物理.h>
#include <core/空间划分/球形八叉树.h>





class C_合并数据节点 : public C_节点基类 {

public:
	C_合并数据节点(S_设备环境& ctx);
	~C_合并数据节点();

	S_Props		m_转换后类型;

	bool	f_update();
	std::string	DEF_节点编译函数;

	void	f_合并物体(std::vector<S_物体*>& obs);

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建合并数据节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载合并数据节点(S_设备环境& ctx, FILE* f);
void		f_node_保存合并数据节点(C_节点基类* n, FILE* f);



class C_转换数据节点 : public C_节点基类 {

public:
	C_转换数据节点(S_设备环境& ctx);
	~C_转换数据节点();

	E_值类型	m_转换数据类型;
	S_Props		m_转换后类型;

	bool			f_update();
	//S_插座增减方式	f_动态增减插座(E_插座输出方向 方向);
	void			f_物体数据转换(uint8 转换后类型, const std::vector<S_物体*>& objs);
	void			f_VN数据转换(uint8 转换后类型, const std::vector<S_VN>& objs);
};

C_节点基类* f_node_加载转换数据节点(S_设备环境& ctx, FILE* f);
void		f_node_保存转换数据节点(C_节点基类* n, FILE* f);



class C_取成员数据节点 : public C_节点基类 {
	std::vector<S_Props> m_不同输入数据成员类型;

public:
	C_取成员数据节点(S_设备环境& ctx);
	~C_取成员数据节点();

	S_Props		m_成员;

	void		f_插座连接事件(C_插座基类* 发生链接的输入插座);
	void		f_get物理引擎成员(uint8 成员, S_Physics* 解算器);
	void		f_get网格成员(uint8 成员, const std::vector<S_Mesh*>& meshs);
	void		f_get向量成员(uint8 成员, const std::vector<vec3>& meshs);
	void		f_get八叉树成员(uint8 成员, const S_点距八叉树& tree);
	void		f_get路径树成员(uint8 成员, const std::vector<S_八叉树子空间*>& treePath);
	bool		f_update();
	void		f_get体素成员(uint8 成员, S_体素& 体素);
};

C_节点基类* f_node_创建取成员数据节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载取成员数据节点(S_设备环境& ctx, FILE* f);
void		f_node_保存取成员数据节点(C_节点基类* n, FILE* f);





class C_从坐标取数据节点 : public C_节点基类 {
	//S_Props m_成员类型;
	std::vector<vec3> m_粒子数据;
	bool m_是否多线程;
public:
	C_从坐标取数据节点(S_设备环境& ctx);
	~C_从坐标取数据节点();

	S_Props		m_成员;
	void		f_异步解算();
	bool		f_update();
	std::string	DEF_节点编译函数;

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建从坐标取数据节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载从坐标取数据节点(S_设备环境& ctx, FILE* f);
void		f_node_保存从坐标取数据节点(C_节点基类* n, FILE* f);




class C_单值钳制节点 : public C_节点基类 {

public:
	C_单值钳制节点(S_设备环境& ctx);
	~C_单值钳制节点();

	S_Props	m_区间;

	bool		f_update();
	std::string	DEF_节点编译函数;

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);

};

C_节点基类* f_node_创建单值钳制节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载单值钳制节点(S_设备环境& ctx, FILE* f);
void		f_node_保存单值钳制节点(C_节点基类* n, FILE* f);



class C_矢量钳制节点 : public C_节点基类 {

public:
	C_矢量钳制节点(S_设备环境& ctx);
	~C_矢量钳制节点();

	S_Props	m_改变原数据;

	bool		f_update();
	std::string	DEF_节点编译函数;

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);

};

C_节点基类* f_node_创建矢量钳制节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载矢量钳制节点(S_设备环境& ctx, FILE* f);
void		f_node_保存矢量钳制节点(C_节点基类* n, FILE* f);




class C_数值转换节点 : public C_节点基类 {

public:
	C_数值转换节点(S_设备环境& ctx);
	~C_数值转换节点();

	E_值类型	m_转换数据类型;
	S_Props		m_转换后类型;

	bool			f_update();
};

C_节点基类* f_node_创建数值转换节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载数值转换节点(S_设备环境& ctx, FILE* f);
void		f_node_保存数值转换节点(C_节点基类* n, FILE* f);



class C_取内存邻接数据节点 : public C_节点基类 {
	
public:
	C_取内存邻接数据节点(S_设备环境& ctx);
	~C_取内存邻接数据节点();

	bool		f_update();
	std::string	DEF_节点编译函数;
	std::string f_生成元素引用代码(E_值类型 type, const std::string& name, std::string& 数组, std::string& 元素ID);
	
};

C_节点基类* f_node_创建取内存邻接数据节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载取内存邻接数据节点(S_设备环境& ctx, FILE* f);
void		f_node_保存取内存邻接数据节点(C_节点基类* n, FILE* f);



class C_取空间邻接数据节点 : public C_节点基类 {

public:
	C_取空间邻接数据节点(S_设备环境& ctx);
	~C_取空间邻接数据节点();

	S_Props		m_空间类型;
	S_Props		m_填充;

	bool		f_update();
	std::string	DEF_节点编译函数;
	
	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建取空间邻接数据节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载取空间邻接数据节点(S_设备环境& ctx, FILE* f);
void		f_node_保存取空间邻接数据节点(C_节点基类* n, FILE* f);



class C_数组打乱节点 : public C_节点基类 {

public:
	C_数组打乱节点(S_设备环境& ctx);
	~C_数组打乱节点();

	//S_Props		m_排序方式;
	//S_Props		m_排序算法;
	S_Props		m_拷贝原数据;

	bool		f_update();
	std::string	DEF_节点编译函数;

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建数组打乱节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载数组打乱节点(S_设备环境& ctx, FILE* f);
void		f_node_保存数组打乱节点(C_节点基类* n, FILE* f);


class C_索引数组排序节点 : public C_节点基类 {

public:
	C_索引数组排序节点(S_设备环境& ctx);
	~C_索引数组排序节点();

	S_Props		m_排序方式;
	S_Props		m_排序算法;
	//S_Props		m_拷贝原数据;

	bool		f_update();
	std::string	DEF_节点编译函数;

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建索引数组排序节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载索引数组排序节点(S_设备环境& ctx, FILE* f);
void		f_node_保存索引数组排序节点(C_节点基类* n, FILE* f);



class C_数组重排节点 : public C_节点基类 {

public:
	C_数组重排节点(S_设备环境& ctx);
	~C_数组重排节点();

	S_Props		m_改变原数据;

	bool		f_update();
	std::string	DEF_节点编译函数;

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建数组重排节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载数组重排节点(S_设备环境& ctx, FILE* f);
void		f_node_保存数组重排节点(C_节点基类* n, FILE* f);



class C_数组抽取节点 : public C_节点基类 {

public:
	C_数组抽取节点(S_设备环境& ctx);
	~C_数组抽取节点();

	S_Props		m_改变原数据;
	S_Props		m_抽取方式;

	bool		f_update();
	std::string	DEF_节点编译函数;

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建数组抽取节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载数组抽取节点(S_设备环境& ctx, FILE* f);
void		f_node_保存数组抽取节点(C_节点基类* n, FILE* f);



class C_坐标取数据节点 : public C_节点基类 {

public:
	C_坐标取数据节点(S_设备环境& ctx);
	~C_坐标取数据节点();

	S_Props		m_空间类型;

	bool		f_update();
	std::string	DEF_节点编译函数;

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建坐标取数据节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载坐标取数据节点(S_设备环境& ctx, FILE* f);
void		f_node_保存坐标取数据节点(C_节点基类* n, FILE* f);




class C_数组切片节点 : public C_节点基类 {

public:
	C_数组切片节点(S_设备环境& ctx);
	~C_数组切片节点();

	S_Props		m_切片轴向;

	bool		f_update();
	std::string	DEF_节点编译函数;

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建数组切片节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载数组切片节点(S_设备环境& ctx, FILE* f);
void		f_node_保存数组切片节点(C_节点基类* n, FILE* f);




//class C_组合数组节点 : public C_节点基类 {
//
//public:
//	C_组合数组节点(S_设备环境& ctx);
//	~C_组合数组节点();
//
//	S_Props		m_空间类型;
//
//	bool		f_update();
//	std::string	DEF_节点编译函数;
//
//	void	f_读取(FILE* f);
//	void	f_写入(FILE* f);
//};
//
//C_节点基类* f_node_创建坐标取数据节点(S_设备环境& ctx, C_节点树* 子节点树);
//C_节点基类* f_node_加载坐标取数据节点(S_设备环境& ctx, FILE* f);
//void		f_node_保存坐标取数据节点(C_节点基类* n, FILE* f);





